from flask import current_app, g
from flask_restful import inputs
from flask_restful import Resource, reqparse

from toutiao import db
from . import constants
from toutiao.utils import parsers
from toutiao.utils.token import get_user_token
from toutiao.utils.decorators import loginrequired
from models.user import User
from cache.user import UserProfileCache, UserStatusCache

from random import choice  # 随机抽取一个值
from string import digits  # 10进制的10个数字（0-9）
from datetime import datetime


# 定义类视图
# 注册登陆
class LoginResource(Resource):
    """注册登陆"""
    def post(self):

        # 接受检验参数
        parser = reqparse.RequestParser()
        parser.add_argument('mobile', location='json', required=True, type=parsers.check_mobile)
        parser.add_argument('code', location='json', required=True, type=inputs.regex(r'\d{6}'))
        args = parser.parse_args()
        mobile = args.get('mobile')
        client_sms_code = args.get('code')

        # 判断验证码是否正确
        key = "app:code:{}".format(mobile)
        server_sms_code = current_app.redis_store.get(key)

        if not server_sms_code or server_sms_code.decode() != client_sms_code:
            return {'message': 'Invalid code.'}, 400

        # 判断用户是否存在
        user = None
        try:
            # user = User.query.filter_by(mobile = mobile).first()
            user = User.query.filter(User.mobile == mobile).first()
        except Exception as e:
            current_app.logger.error(e)

        if user is None:
            # 不存在则保存到数据库
            user = User()
            user_id = current_app.id_worker.get_id()
            user.id = user_id
            user.mobile = mobile
            user.name = mobile
            user.last_login = datetime.now()
            try:
                db.session.add(user)
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)
                db.session.rollback()
        else:
            # 保存最新的登陆时间
            user.last_login = datetime.now()
            try:
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)

        # 生成token
        token, refresh_token = get_user_token(user.id)

        # 添加缓存
        UserProfileCache(user.id).save()
        UserStatusCache(user.id).save(user.status)

        # 存在不存在都返回json
        return {
            'token': token,
            'refresh_token': refresh_token
                }

    def put(self):
        """
        刷新token，token过期时，前端会把refresh发过来，我们根据这个在生成一个token
        :return: token
        """
        # 先判断user_id 和 refresh_token是否都存在
        if g.user_id and g.refresh:
            # 判断用户状态，是否异常
            from cache.user import UserStatusCache
            user_enable = UserStatusCache(g.user_id).get()
            if not user_enable:
                # 异常，则返回403
                return {'message': 'User denied.'}, 403
            # 正常，则生成token,返回token
            # 存在则生成新的token
            token, refresh_token = get_user_token(g.user_id)
            return {'token': token}, 201
        # 不存在则返回403
        else:
            return {'message': 'Wrong refresh token.'}, 403


# 发送短息验证码
class SmsCodeResource(Resource):
    """发送短息验证码"""
    def get(self, mobile):

        # 获取手机号，路径参数，mobile
        # 生成短信验证码,列表推导式
        sms_code = ''.join([choice(digits) for _ in range(6)])
        # 保存短息验证码，保存到redsi数据库
        current_app.redis_store.setex('app:code:{}'.format(mobile), constants.SMS_VERIFICATION_CODE_EXPIRES, sms_code)
        # 响应数据
        return {
            'mobile': mobile
        }


# 压力测试
# 查询用户信息
class UserInfoResource(Resource):
    """查询用户信息"""

    method_decorators = [loginrequired]

    def get(self):
        # user = User.query.filter_by(id=1).first()
        #
        # user_data = {
        #     'id': user.id,
        #     'mobile': user.mobile,
        #     'name': user.name,
        #     'photo': user.profile_photo or '',
        #     'is_media': user.is_media,
        #     'intro': user.introduction or '',
        #     'certi': user.certificate or '',
        # }

        user_id = g.user_id
        user_data = UserProfileCache(user_id).get()

        return user_data


import json


# 查询redis缓存
class CacheUserInfoResource(Resource):

    def get(self):
        redis_data=current_app.redis_store.get(1)
        user_data=json.loads(redis_data.decode())
        return user_data

    # 用户第一次将数据库中的数据保存到缓存
    def post(self):
        user = User.query.filter_by(id=1).first()

        user_data = {
            'id': user.id,
            'mobile': user.mobile,
            'name': user.name,
            'photo': user.profile_photo or '',
            'is_media': user.is_media,
            'intro': user.introduction or '',
            'certi': user.certificate or '',
        }

        current_app.redis_store.set(1, json.dumps(user_data))

        return {'message':'ok'}


